import re
import time
from io import BytesIO

from docx import Document
from lxml import etree

from wechat.webot import *
from zuoyebang.MathUtils import latex_to_oxml

headers = {
    'Accept': 'application/json, text/plain, */*',
    'Accept-Encoding': 'gzip, deflate, br, zstd',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cache-Control': 'no-cache',
    'Pragma': 'no-cache',
    'Priority': 'u=1, i',
    'Sec-Ch-Ua': '"Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"',
    "Sec-Ch-Ua-Mobile": "?0",
    "Sec-Ch-Ua-Platform": '"Windows"',
    "Sec-Fetch-Dest": "empty",
    "Sec-Fetch-Mode": "cors",
    "Sec-Fetch-Site": "same-origin",
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
    # 'X-Cuid': '1BF684D036B3A83A9A2FEE26BF8B28FC|0'
}


def get_questions(url):
    """
    获取问题 会按照<br/> 进行分割
    :param url:
    :return:
    """
    try:
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            response_data = response.json()
            content = response_data.get('data').get('result')[0].get('question').get('content')
            return content.strip().split('<br/>')
        else:
            return []
    except Exception as e:
        logging.warning(f"获取问题失败: {e.args} url: {url}")
        return []


def get_question_img(image_url):
    """
    获取问题中的图片
    :param url: 图片地址
    :return: 图片字节流
    """
    image_response = requests.get(image_url)
    if image_response.status_code == 200:
        return BytesIO(image_response.content)
    else:
        return f"<[这里是一张图片,但是没有获取到? 这是图片地址: {image_url}]>"


question_mark_pattern = r'\$(.+?)\$'


def analyse_question_mark(paragraph, question):
    """
    分析问题中的标记$$
    :param question:
    :return:
    """
    start_index = 0
    index = question.find("$")
    while index != -1:
        # 先把开始的加进来
        paragraph.add_run(question[start_index:index])
        start_index = index
        # 找结尾
        index = question.find("$", index + 1)
        if index != -1:
            mark_content = question[start_index:index + 1]
            # 解析标记并加入到word
            write_question_mark(paragraph, mark_content)
            # 用于下一个循环
            start_index = index + 1
            index = question.find("$", index + 1)
    # 最后剩余的
    if start_index < len(question):
        paragraph.add_run(question[start_index:])


def write_question_mark(paragraph, mark_content):
    mark_content = mark_content.replace(r"$", "")
    # print(mark_content)
    run = paragraph.add_run()
    try:
        run._element.append(latex_to_oxml(mark_content))
    except Exception as e:
        # 转换出了问题
        run.text = mark_content


def write_question_to_word(questions, word_file):
    if len(questions) == 0:
        return
    # 创建一个新的 Word 文档
    doc = Document()
    for question in questions:
        # 创建个段落
        paragraph = doc.add_paragraph()
        # 判断是否是图片
        if "<img" in question:
            match = re.search('<img [^>]*src="([^"]+)".+?[>|(\>)]', question)
            if match:
                image_url = match.group(1)
                paragraph.add_run().add_picture(get_question_img(image_url))
            else:
                paragraph.add_run("<[这里应该是图片的但是没有找到图片]>")
        else:
            # 是文本
            analyse_question_mark(paragraph, question)
    doc.save(f'./temp/{word_file}.docx')


def handleMessageFun(wx_message: WxMessage):
    global search_questions_flag
    global questions_url_list
    # 一定要加上这句，不然会陷入死循环
    if wx_message.is_self_msg != 1:
        # 如果是群消息需要@再回复
        if wx_message.sender:
            if wx_message.content.startswith(f"@{wx_context.self_info.nick_name}"):
                send_msg(base_url, wx_message.wx_id, wx_message.content)
        else:
            if wx_message.msg_type == 1:
                content = wx_message.content
                if "开始搜题" == content:
                    search_questions_flag = True
                    questions_url_list = []
                    send_msg(base_url, wx_message.wx_id,
                             "我已经准备就绪，你可以将作业帮的题目分享给我，当你搜题结束后请说: 【开始生成】我会立马生成对应的试题成一个word. 但是目前我不支持分享word文件你可以在我的服务器中进行下载")
                if "开始生成" == content:
                    if len(questions_url_list) == 0:
                        send_msg(base_url, wx_message.wx_id,
                                 "臭宝你需要分享给我作业帮的试题，但是目前我没有接收到你的分享!(你需要发出【开始搜题】指令我才会记录哦)")
                        return
                    search_questions_flag = False
                    send_msg(base_url, wx_message.wx_id, "正在生成...")
                    try:
                        questions = []
                        for questions_url in questions_url_list:
                            questions += get_questions(questions_url)
                        current_timestamp = time.time()
                        write_question_to_word(questions, current_timestamp)
                        send_msg(base_url, wx_message.wx_id, f"生成word完成:http://192.168.0.107:9000/download/{current_timestamp}.docx")
                    except Exception as e:
                        send_msg(base_url, wx_message.wx_id, "生成word时出现了错误")
                        logging.error(f"生成word时出现了错误:{e.args}")
                    finally:
                        questions_url_list = []
            elif wx_message.msg_type == 49:
                # 解析作业帮连接
                if not search_questions_flag:
                    return
                xml_content = etree.fromstring(wx_message.content)
                url_element = xml_content.find("appmsg/url")
                if url_element is not None:
                    add_questions_url(url_element.text)


share_url_prefix = "https://plat-miniapp.zuoyebang.com/miniapp/share"
questions_url_prefix = "https://plat-miniapp.zuoyebang.com/miniapp/api/questions"


def add_questions_url(questions_url: str) -> bool:
    global questions_url_list
    if questions_url is None:
        logging.warning("未发现作业帮问题url")
        return False
    if not questions_url.startswith(share_url_prefix):
        logging.warning("不是作业帮的分享链接")
        return False
    questions_url_list.append(questions_url.replace(share_url_prefix, questions_url_prefix))

if __name__ == '__main__':
    # 微信机器人的端口
    base_url = "http://127.0.0.1:8989/api"
    # 收集分享的实体
    questions_url_list = []
    # 收集开关
    search_questions_flag = False
    # 获取微信信息上下文
    wx_context = get_wx_context(base_url)
    # 微信消息监听器
    listener = WeMessageListener(handleMessageFun, host='0.0.0.0', port=9000)
